home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
ABUSESRC.ZIP
/
AbuseSrc
/
imlib
/
pmenu.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-04-11
|
11KB
|
462 lines
#include "pmenu.hpp"
void pmenu::move(int new_x, int new_y)
{
wm->move_window(bar,new_x,new_y);
}
pmenu::pmenu(int X, int Y, pmenu_item *first, image *screen, window_manager *wmanager)
{
top=first;
active=NULL;
wm=wmanager;
short cx1,cy1,cx2,cy2;
screen->get_clip(cx1,cy1,cx2,cy2);
if (cx1<X) cx1=X;
int w=cx2-cx1+1;
int h=wm->font()->height()+4;
bar=wm->new_window(X,Y,w-WINDOW_FRAME_LEFT-WINDOW_FRAME_RIGHT,
h-WINDOW_FRAME_TOP-WINDOW_FRAME_BOTTOM,NULL);
bar->set_moveability(0); // can't drag this window
bar->screen->wiget_bar(0,0,w-1,h-1,wm->bright_color(),wm->medium_color(),
wm->dark_color());
int total=0,tx,tw;
pmenu_item *p=top;
for (;p;p=p->next) total++;
tw=w/(total+1);
tx=tw/2;
for (p=top;p;p=p->next,tx+=tw)
p->draw_self(bar,itemx(p,wm),1,itemw(p,wm),1,wm,p==active);
/* }
else
{
for (p=top;p;p=p->next,tx+=tw)
p->draw(bar,itemx(p,wm),1,itemw(p,wm),1,wm,p==active);
}*/
}
pmenu_item::pmenu_item(int ID, char *Name, char *on_off_flag, int Hotkey, pmenu_item *Next)
{
xp=-1;
id=ID;
hotkey=Hotkey;
on_off=on_off_flag;
if (Name)
n=strcpy((char *)jmalloc(strlen(Name)+1,"pmenu_item::name"),Name);
else n=NULL;
next=Next;
sub=NULL;
}
pmenu_item::pmenu_item(char *Name, psub_menu *Sub, pmenu_item *Next, int xpos)
{
xp=xpos;
id=0; hotkey=-1;
next=Next;
on_off=NULL;
CONDITION(Name,"Sub menu cannot have a NULL name");
n=strcpy((char *)jmalloc(strlen(Name)+1,"pmenu_item::name"),Name);
sub=Sub;
}
pmenu_item *pmenu_item::find_id(int search_id)
{
if (id==search_id) return this;
else if (sub) return sub->find_id(search_id);
else return NULL;
}
pmenu_item *pmenu_item::find_key(int key)
{
if (key==hotkey && hotkey!=-1) return this;
else if (sub) return sub->find_key(key);
else return NULL;
}
pmenu::~pmenu()
{
while (top)
{
pmenu_item *p=top;
top=top->next;
delete p;
}
if (bar) wm->close_window(bar);
}
psub_menu::~psub_menu()
{
if (win)
wm->close_window(win);
while (first)
{
pmenu_item *tmp=first;
first=first->next;
delete tmp;
}
}
pmenu_item *psub_menu::find_id(int search_id)
{
for (pmenu_item *f=first;f;f=f->next)
{
pmenu_item *ret=f->find_id(search_id);
if (ret) return ret;
}
return NULL;
}
pmenu_item *psub_menu::find_key(int key)
{
for (pmenu_item *f=first;f;f=f->next)
{
pmenu_item *ret=f->find_key(key);
if (ret) return ret;
}
return NULL;
}
void psub_menu::hide(jwindow *parent, int x, int y, window_manager* wm)
{
int w,h;
calc_size(w,h,wm);
short cx1,cy1,cx2,cy2;
screen->get_clip(cx1,cy1,cx2,cy2);
if (w+x>cx2)
x=cx2-w;
if (win)
{
if (active!=-1)
{
int w,h;
calc_size(w,h,wm);
item_num(active)->draw(win,x+3,y+3+active*(wm->font()->height()+1),w-6,0,wm,0);
}
wm->close_window(win);
win=NULL;
}
}
void psub_menu::calc_size(int &w, int &h, window_manager *wm)
{
int tw=wm->font()->width(),th=wm->font()->height();
w=h=0;
for (pmenu_item *p=first;p;p=p->next)
{
if (p->name())
{
int l=strlen(p->name())*tw+8;
if (p->on_off) l+=tw*4;
if (l>w) w=l;
}
h++;
}
h=h*(th+1)+8;
}
void psub_menu::draw(jwindow *parent, int x, int y, window_manager *wmanager)
{
if (win) wm->close_window(win);
wm=wmanager;
int w,h,i=0;
calc_size(w,h,wm);
short cx1,cy1,cx2,cy2;
screen->get_clip(cx1,cy1,cx2,cy2);
if (parent->x+w+x>cx2)
x=cx2-w-parent->x;
if (h+y+parent->y>cy2)
if (parent->y+parent->h+wm->font()->height()>cy2)
y=-h;
else y=y-h+wm->font()->height()+5;
win=wm->new_window(parent->x+x,parent->y+y,
w-WINDOW_FRAME_LEFT-WINDOW_FRAME_RIGHT,
h-WINDOW_FRAME_TOP-WINDOW_FRAME_BOTTOM,NULL);
win->set_moveability(0);
win->screen->wiget_bar(0,0,w-1,h-1,wm->bright_color(),wm->medium_color(),wm->dark_color());
int has_flags=0;
pmenu_item *p=first;
for (;p;p=p->next) if (p->on_off) has_flags=1;
x=has_flags ? 3+wm->font()->width() : 3;
y=3;
for (p=first;p;p=p->next,i++,y+=wm->font()->height()+1)
p->draw(win,x,y,w-6,0,wm,i==active);
}
void pmenu_item::draw_self(jwindow *parent, int x, int y, int w, int top, window_manager *wm, int active)
{
int bx=x;
if (on_off) bx=x-wm->font()->width();
if (!n)
{
int h=wm->font()->height();
parent->screen->wiget_bar(x,y+h/2-1,x+w-1,y+h/2,wm->dark_color(),wm->medium_color(),wm->bright_color());
} else
{
if (active)
{
if (xp!=-1)
parent->screen->xor_bar(bx,y,x+w-1,y+wm->font()->height()+1,wm->dark_color());
else
{
parent->screen->bar(bx,y,x+w-1,y+wm->font()->height()+1,wm->dark_color());
wm->font()->put_string(parent->screen,x+1,y+1,n,wm->medium_color());
if (on_off && *on_off) wm->font()->put_string(parent->screen,bx+1,y+1,"*",wm->medium_color());
}
} else
{
if (xp!=-1)
parent->screen->xor_bar(bx,y,x+w-1,y+wm->font()->height()+1,wm->dark_color());
else
{
parent->screen->bar(bx,y,x+w-1,y+wm->font()->height()+1,wm->medium_color());
wm->font()->put_string(parent->screen,x+1,y+1,n,wm->bright_color());
if (on_off && *on_off) wm->font()->put_string(parent->screen,bx+1,y+1,"*",wm->bright_color());
}
}
}
}
void pmenu_item::draw(jwindow *parent, int x, int y, int w, int top,
window_manager *wm, int active)
{
if (n)
{
if (active)
{
draw_self(parent,x,y,w,top,wm,active);
if (sub)
{
if (top)
sub->draw(parent,x,y+wm->font()->height()+2,wm);
else
sub->draw(parent,x+w,y,wm);
}
}
else
{
if (sub)
{
if (top)
sub->hide(parent,x,y+wm->font()->height()+2,wm);
else
sub->hide(parent,x+w,y,wm);
}
draw_self(parent,x,y,w,top,wm,active);
}
} else draw_self(parent,x,y,w,top,wm,active);
}
int pmenu::itemx(pmenu_item *p, window_manager *wm)
{
if (p->xp!=-1) return p->xp;
int w=bar->screen->width();
int total=0,tx,tw,i=0,x;
for (pmenu_item *pp=top;pp;pp=pp->next,i++)
{ if (pp==p) x=i;
total++;
}
tw=w/(total+1);
return tw/2+x*tw;
}
void pmenu::draw(image *screen, window_manager *wm, int top_only)
{
}
int psub_menu::handle_event(jwindow *parent, int x, int y, window_manager *wm, event &ev)
{
int w,h;
calc_size(w,h,wm);
short cx1,cy1,cx2,cy2;
screen->get_clip(cx1,cy1,cx2,cy2);
x=win->x;
y=win->y;
int has_flags=0,dx=3;
for (pmenu_item *p=first;p;p=p->next) if (p->on_off) has_flags=1;
if (has_flags) dx+=wm->font()->width();
int th=wm->font()->height();
if (ev.mouse_move.x>=x && ev.mouse_move.y>=y && ev.mouse_move.x<x+w && ev.mouse_move.y<y+h)
{
int new_active=(ev.mouse_move.y-y-3)/(th+1);
if (item_num(new_active)==NULL) new_active=-1;
if (new_active!=active)
{
if (active!=-1)
item_num(active)->draw(win,dx,3+active*(th+1),w-6,0,wm,0);
active=new_active;
if (active!=-1)
item_num(active)->draw(win,dx,3+active*(th+1),w-6,0,wm,1);
}
if (ev.type==EV_MOUSE_BUTTON)
{
if (active!=-1)
return item_num(active)->handle_event(win,dx,3+active*(th+1),w-6,0,wm,ev);
else return 0;
} else return 1;
} else if (active!=-1)
return item_num(active)->handle_event(win,win->x+dx,win->y+3+active*(th+1),w-6,0,wm,ev);
else return 0;
}
int pmenu_item::handle_event(jwindow *parent, int x, int y, int w, int top,
window_manager *wm, event &ev)
{
x+=parent->x;
y+=parent->y;
if (ev.mouse_move.x>=x && ev.mouse_move.y>=y && ev.mouse_move.x<x+w &&
ev.mouse_move.y<y+wm->font()->height()+2)
{
if (sub) return 1;
else
{
if (ev.type==EV_MOUSE_BUTTON &&n)
wm->push_event(new event(id,(char *)this));
return 1;
}
} else if (sub)
{
if (top)
return sub->handle_event(parent,x,y+wm->font()->height()+2,wm,ev);
else return sub->handle_event(parent,x+w,y,wm,ev);
} else return 0;
}
pmenu_item *pmenu::inarea(int mx, int my, image *screen, window_manager *wm)
{
short cx1,cy1,cx2,cy2;
screen->get_clip(cx1,cy1,cx2,cy2);
mx-=bar->x;
my-=bar->y;
if (mx<0 || my<0 || mx>=bar->screen->width() || my>=bar->screen->height()) return NULL;
else
{
for (pmenu_item *p=top;p;p=p->next)
{
if (!p->next) return p;
else if (itemx(p->next,wm)>mx) return p;
}
return NULL;
}
}
int psub_menu::own_event(event &ev)
{
if (win && ev.window==win) return 1; else
for (pmenu_item *p=first;p;p=p->next)
if (p->own_event(ev))
return 1;
return 0;
}
int pmenu_item::own_event(event &ev)
{
if (sub)
return sub->own_event(ev);
else return 0;
}
pmenu_item::~pmenu_item()
{ if (n) jfree(n); if (sub) delete sub;
}
int pmenu::handle_event(event &ev, image *screen, window_manager *wm)
{
if (!active && ev.window!=bar) return 0;
/*
int yes=0;
if (ev.window==bar) yes=1; // event in top bar?
else
{
for (pmenu_item *p=top;p && !yes;p=p->next) // event in submenu?
if (p->own_event(ev)) yes=1;
}
if (!yes) return 0; // event is not for us...
}*/
switch (ev.type)
{
case EV_KEY :
{
for (pmenu_item *p=top;p;p=p->next)
{
pmenu_item *r=p->find_key(ev.key);
if (r)
{
wm->push_event(new event(r->id,(char *)r));
return 1;
}
}
return 0;
} break;
case EV_MOUSE_MOVE :
{
pmenu_item *new_selection=inarea(ev.mouse_move.x,ev.mouse_move.y,screen,wm);
if (!new_selection && active &&
active->handle_event(bar,itemx(active,wm),1,itemw(active,wm),1,wm,ev))
return 1;
else if (active!=new_selection)
{
if (active)
active->draw(bar,itemx(active,wm),1,itemw(active,wm),1,wm,0);
active=new_selection;
if (active)
active->draw(bar,itemx(active,wm),1,itemw(active,wm),1,wm,1);
}
if (active) return 1;
else return 0;
} break;
case EV_MOUSE_BUTTON :
{
if (active)
{
if (active->handle_event(bar,itemx(active,wm),1,itemw(active,wm),1,wm,ev))
{
active->draw(bar,itemx(active,wm),1,itemw(active,wm),1,wm,0);
active=NULL;
return 1;
} else return 0;
}
else return 0;
} break;
}
return 0;
}